﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.Threading;
using System.Net.Sockets;

namespace Wantn.SMS.SerialServer
{
    public class LDS50_bak : IDisposable
    {
        /// <summary>
        /// 
        /// </summary>
        /// <param name="ip"></param>
        /// <param name="port"></param>
        public LDS50_bak(string ip, int port)
        {
            E_IP = ip;
            E_Port = port;
            E_Interval = 500;
        }

        /// <summary>
        /// 
        /// </summary>
        public string E_IP { set; get; }
        /// <summary>
        /// 
        /// </summary>
        public int E_Port { set; get; }

        public int E_Interval { set; get; }

        /// <summary>
        /// 同步返回事件
        /// </summary>
        public event EventHandler<CommonEventArgs> ReadEvent;
        /// <summary>
        /// 重量读取线程
        /// </summary>
        private Thread _thrdRead;
        /// <summary>
        /// 线程控制开关
        /// </summary>
        private bool _bRun = false;
        /// <summary>
        /// TCP客户端对象
        /// </summary>
        private TcpClient tcpClient;
        /// <summary>
        /// TCP数据操作流
        /// </summary>
        private NetworkStream ntwStream;

        /// <summary>
        /// 
        /// </summary>
        public void DoRead()
        {
            _bRun = true;
            _thrdRead = new Thread(new ThreadStart(DoReadListening));
            _thrdRead.IsBackground = true;
            _thrdRead.Start();
        }

        /// <summary>
        /// 停止激光测距数据读取
        /// </summary>
        public void DoStop()
        {
            _bRun = false;
            System.Threading.Thread.Sleep(E_Interval);
            if (_thrdRead != null)
                _thrdRead.Abort();
        }

        private void DoReConnect()
        {
            DoReadListening();
        }

        /// <summary>
        /// 激光测距数据读取
        /// </summary>
        private void DoReadListening()
        {
            bool _bNeedReSend = false;
            System.Threading.Thread.Sleep(2000);
            Log.WriteLogBackServices("尝试连接激光测距");
            try
            {
                tcpClient = new TcpClient();
                tcpClient.SendTimeout = 2000;
                tcpClient.ReceiveTimeout = 2000;
                tcpClient.Connect(E_IP, E_Port);
                ntwStream = tcpClient.GetStream();

                Byte[] _byCmd = new Byte[8];
                _byCmd[0] = 0x01;
                _byCmd[1] = 0x03;
                _byCmd[2] = 0x00;
                _byCmd[3] = 0x15;
                _byCmd[4] = 0x00;
                _byCmd[5] = 0x02;
                _byCmd[6] = 0xD5;
                _byCmd[7] = 0xCF;

                Byte[] _bySendStart = new Byte[8];
                _bySendStart[0] = 0x01;
                _bySendStart[1] = 0x06;
                _bySendStart[2] = 0x00;
                _bySendStart[3] = 0x11;
                _bySendStart[4] = 0x00;
                _bySendStart[5] = 0x02;
                _bySendStart[6] = 0x58;
                _bySendStart[7] = 0x0E;

                if (ntwStream.CanRead)
                {
                    //接收状态,长度<1024字节
                    byte[] bytes;
                    string _strReadData, _strAnalysis;
                    int byteLength;
                    decimal _dValue = 0;
                    bytes = new Byte[1024];
                    //每次连接，下发一次连续测量命令
                    ntwStream.Write(_bySendStart, 0, _bySendStart.Length);
                    System.Threading.Thread.Sleep(200);
                    ntwStream.Read(bytes, 0, bytes.Length);
                    System.Threading.Thread.Sleep(3000);
                    while (_bRun)
                    {
                        try
                        {
                            //单次触发测量
                            ntwStream.Write(_byCmd, 0, _byCmd.Length);
                            //读取数据
                            System.Threading.Thread.Sleep(100);
                            bytes = new Byte[1024];
                            _strReadData = string.Empty;
                            byteLength = ntwStream.Read(bytes, 0, bytes.Length);
                            if (byteLength > 0)
                            {
                                _strReadData = "";
                                for (int i = 0; i < bytes.Length; i++)
                                {
                                    _strReadData = _strReadData + bytes[i].ToString("X").PadLeft(2, '0') + " ";
                                }
                                if (_strReadData.IndexOf("01 03 04", 0) >= 0)
                                {
                                    _strAnalysis = _strReadData.Substring(_strReadData.IndexOf("01 03 04"), 24).Substring(9, 12).Replace(" ", "");
                                    _dValue = decimal.Parse((GetHexadecimalValue(_strAnalysis) * 1.0 / 10000).ToString("F4"));

                                    if (_dValue > 50 || _dValue < 0)
                                    {
                                        _bNeedReSend = true;
                                        Log.WriteLogBackServices(string.Format("激光测距数据:{0}，自动进行重连", _dValue));
                                    }
                                    if (!_bNeedReSend)
                                    {
                                        if (MomeryCenter.M_CurtainCount > 0 && _dValue > 5)
                                        {
                                            _bNeedReSend = true;
                                            Log.WriteLogBackServices(string.Format("当前光幕遮挡:{0}，激光测距值:{1}，系统判定异常，自动进行重连", MomeryCenter.M_CurtainCount, _dValue));
                                        }
                                    }
                                    if (_bNeedReSend || MomeryCenter.E_NeedReConnet)
                                    {
                                        _bNeedReSend = false;
                                        MomeryCenter.E_NeedReConnet = false;
                                        //重连
                                        ntwStream.Close();
                                        tcpClient.Close();
                                        System.Threading.Thread.Sleep(2000);

                                        tcpClient = new TcpClient();
                                        tcpClient.Connect(E_IP, E_Port);
                                        ntwStream = tcpClient.GetStream();
                                        //每次连接，下发一次连续测量命令
                                        ntwStream.Write(_bySendStart, 0, _bySendStart.Length);
                                        System.Threading.Thread.Sleep(200);
                                        ntwStream.Read(bytes, 0, bytes.Length);
                                        System.Threading.Thread.Sleep(3000);
                                    }
                                    else
                                    {
                                        _bNeedReSend = false;
                                        EventHelper.DispatchEventAsync<CommonEventArgs>(this, this.ReadEvent, new CommonEventArgs(_dValue));
                                    }
                                }
                            }
                            System.Threading.Thread.Sleep(2000);
                        }
                        catch (Exception ex)
                        {
                            EventHelper.DispatchEventAsync<CommonEventArgs>(this, this.ReadEvent, new CommonEventArgs("激光测距数据读取失败，正在尝试重连"));
                            Log.WriteLogBackServices("激光测距数据读取失败，正在尝试重连");
                            Log.WriteLogBackServices(ex.ToString());
                            System.Threading.Thread.Sleep(5000);
                            try
                            {
                                ntwStream.Close();
                                tcpClient.Close();
                                System.Threading.Thread.Sleep(2000);

                                tcpClient = new TcpClient();
                                tcpClient.Connect(E_IP, E_Port);
                                ntwStream = tcpClient.GetStream();
                                //每次连接，下发一次连续测量命令
                                ntwStream.Write(_bySendStart, 0, _bySendStart.Length);
                                System.Threading.Thread.Sleep(3000);
                                Log.WriteLogBackServices("激光测距数据读取失败，重连成功");
                            }
                            catch (Exception exx)
                            {
                                Log.WriteLogBackServices("激光测距数据读取失败，系统重连出错");
                                Log.WriteLogBackServices(exx.ToString());
                            }
                        }
                    }
                    ntwStream.Close();
                    tcpClient.Close();
                }
                else
                {
                    ntwStream.Close();
                    tcpClient.Close();
                }
            }
            catch (Exception ex)
            {
                EventHelper.DispatchEventAsync<CommonEventArgs>(this, this.ReadEvent, new CommonEventArgs("激光测距数据读取失败，正在尝试重连"));
                Log.WriteLogBackServices("激光测距数据读取失败..无法重连!!");
                Log.WriteLogBackServices(ex.ToString());
            }
        }

        /// <summary>
        /// 十六进制换算为十进制
        /// </summary>
        /// <param name="strColorValue"></param>
        /// <returns></returns>
        public static int GetHexadecimalValue(String strColorValue)
        {
            char[] nums = strColorValue.ToCharArray();
            int total = 0;
            try
            {
                for (int i = 0; i < nums.Length; i++)
                {
                    String strNum = nums[i].ToString().ToUpper();
                    switch (strNum)
                    {
                        case "A":
                            strNum = "10";
                            break;
                        case "B":
                            strNum = "11";
                            break;
                        case "C":
                            strNum = "12";
                            break;
                        case "D":
                            strNum = "13";
                            break;
                        case "E":
                            strNum = "14";
                            break;
                        case "F":
                            strNum = "15";
                            break;
                        default:
                            break;
                    }
                    double power = Math.Pow(16, Convert.ToDouble(nums.Length - i - 1));
                    total += Convert.ToInt32(strNum) * Convert.ToInt32(power);
                }

            }
            catch (System.Exception ex)
            {
                String strErorr = ex.ToString();
                return 0;
            }


            return total;
        }


        #region 释放托管资源
        private bool IsDisposed = false;
        /// <summary>
        /// 释放资源
        /// </summary>
        public virtual void Dispose()
        {
            if (!this.IsDisposed)
            {
                try
                {
                    if (_thrdRead != null)
                    {
                        _bRun = false;
                        System.Threading.Thread.Sleep(200);
                        _thrdRead.Abort();
                    }
                    ntwStream.Close();
                    tcpClient.Close();
                }
                finally
                {
                    this.IsDisposed = true;
                    GC.SuppressFinalize(this);
                }
            }
        }
        #endregion


    }
}
